package org.web.common.sso.client.biz.impl;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.web.base.domain.helper.ServiceExceptionHelper;
import org.web.base.helper.PropertiesHelper;
import org.web.base.helper.StringHelper;

import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.*;

@Setter
@Getter
@ToString
public class SSOAbstractFilterConfig implements PropertiesConstantInterface {

    private static Logger logger = LoggerFactory.getLogger(SSOAbstractFilterConfig.class);

    // 免登陆URI信息，分号分隔，并用于生成ignoreURIList;
    private String ignoreURIStr;
    // generate by ignoreURIStr when init method executing.
    private List<String> ignoreURIList;
    // token 的参数名称
    private String paramToken = null;
    // 初始化必须进行配置
    private String redirectURL = null;

    private CookieRule cookieRule;
    // 本地IP
    private List<String> localIPList;
    // 后续兼容适配预留字段。
    private String ssoVersion;
    // 默认按有域名，基于域名写入cookie的方式处理。
    private Boolean isCookieWay = true;

    public static void init(SSOAbstractFilterConfig config) throws RuntimeException {

        // 获取SSO独立配置文件，如果不存在，默认从application文件中获取。
        ResourceBundle resourceBundle = getResourceBundle();

        // token 的默认名称是ssoToken，可以不进行配置。
        config.setParamToken(PropertiesHelper.getString(resourceBundle, PROPERTIES_TOKEN_NAME, PROPERTIES_TOKEN_NAME_DEFAULT_VALUE));

        // 初始化免登陆URLS。
        String ignoreURLS = PropertiesHelper.getString(resourceBundle, PROPERTIES_IGNORE_LIST, null);
        if (StringUtils.isNoneBlank(ignoreURLS)) {
            config.setIgnoreURIStr(ignoreURLS);
            config.setIgnoreURIList(StringHelper.transStr2List(ignoreURLS, ";", String.class));
        } else {
            config.setIgnoreURIList(new ArrayList<>());
        }


        // 初始化CookieRule
        CookieRule cookieRule = new CookieRule(); // 默认值见CookieRule ，private定义的初始值。
        cookieRule.setCookiePath(PropertiesHelper.getString(resourceBundle, PROPERTIES_COOKIE_PATH, cookieRule.getCookiePath()));
        cookieRule.setCookieSecure(PropertiesHelper.getBooelan(resourceBundle, PROPERTIES_COOKIE_SECURE, cookieRule.isCookieSecure()));
        cookieRule.setCookieVersion(PropertiesHelper.getInteger(resourceBundle, PROPERTIES_COOKIE_VERSION, cookieRule.getCookieVersion()));
        cookieRule.setCookieHttpOnly(PropertiesHelper.getBooelan(resourceBundle, PROPERTIES_COOKIE_HTTP_ONLY, cookieRule.isCookieHttpOnly()));
        cookieRule.setCookieMaxAge(PropertiesHelper.getInteger(resourceBundle, PROPERTIES_COOKIE_MAX_AGE, cookieRule.getCookieMaxAge()));
        config.setCookieRule(cookieRule);
        config.setLocalIPList(getLocalAddress());
        config.setSsoVersion(PropertiesHelper.getString(resourceBundle, PROPERTIES_SSO_VERSION, PROPERTIES_SSO_VERSION_DEFAULT_VALUE));
        config.setIsCookieWay(PropertiesHelper.getBooelan(resourceBundle, PROPERTIES_IS_COOKIE_WAY, true));

    }

    public static ResourceBundle getResourceBundle() {
        ResourceBundle resourceBundle = ResourceBundle.getBundle(PROPERTIES_FILE_NAME_DEFAULT_VALUE);
        String propertiesName = PropertiesHelper.getString(resourceBundle, PROPERTIES_FILE_NAME, PROPERTIES_FILE_NAME_DEFAULT_VALUE);
        if (!StringUtils.equals(propertiesName, PROPERTIES_FILE_NAME_DEFAULT_VALUE)) {
            resourceBundle = ResourceBundle.getBundle(propertiesName);
        }
        return resourceBundle;
    }

    private static List<String> getLocalAddress() {
        List<String> list = new LinkedList<>();
        try {
            Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
            while (enumeration.hasMoreElements()) {
                NetworkInterface network = enumeration.nextElement();
                if (!network.isVirtual() && network.isUp()) {
                    Enumeration<InetAddress> addresses = network.getInetAddresses();
                    while (addresses.hasMoreElements()) {
                        InetAddress address = addresses.nextElement();
                        if (address != null)
                            if (address instanceof Inet4Address || address instanceof Inet6Address) {
                                list.add(address.getHostAddress());
                            }
                    }
                }
            }
        } catch (Exception e) {
            logger.error(ServiceExceptionHelper.getExceptionInfo(e));
        }
        return list;
    }

}